package com.simpleframe.persistence.hibernate;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;

import com.simpleframe.domain.type.Type;

public class Finder {
	
	private StringBuffer hqlBuffer;
	private String order;
	private String pageOrder;
	private int pageSize;
	private int pageNo;
	private boolean cacheable;
	private Map<String, Object> parameters;
	
	private Searchers searchers;

	private Finder(String hql){
		checkHQL(hql);
		hqlBuffer = new StringBuffer(hql);
	}
	
	public static Finder create(String hql){
		return new Finder(hql);
	}
	
	public static Finder create(Class<?> clazz){
		return new Finder("from "+clazz.getSimpleName()+" where 1=1 ");
	}
	
	/**
	 * 等于
	 * @param name
	 * @param value
	 * @return
	 */
	public Finder andEq(String name, Object value){
		append("and "+name+"=:"+name.replaceAll("\\.", "_")+" ");
		setValue(name, value);
		return this;
	}
	
	/**
	 * 大于
	 * @param name
	 * @param value
	 * @return
	 */
	public Finder andGt(String name, Object value){
		append("and "+name+">:"+name.replaceAll("\\.", "_")+" ");
		setValue(name, value);
		return this;
	}
	
	/**
	 * 小于
	 * @param name
	 * @param value
	 * @return
	 */
	public Finder andLt(String name, Object value){
		append("and "+name+"<:"+name.replaceAll("\\.", "_")+" ");
		setValue(name, value);
		return this;
	}
	
	public Finder append(String hql){
		checkHQL(hql);
		hqlBuffer.append(hql);
		return this;
	}
	
	public Finder addOrder(String defaultOrder){
		if(defaultOrder != null && !defaultOrder.trim().equals("")){
			this.order = defaultOrder;
		}
		//else{
		//	this.order = "order by "+order.replace("+", " ");//+" desc ";
		//}
		return this;
	}
	
	public Finder addPageOrder(String order){
		if(order != null && !order.trim().equals("")){
			this.pageOrder = order;
		}
		return this;
	}
	
	public String getPageOrder(){
		return pageOrder;
	}
	
	
//	public Finder add(Condition condition){
//		if(searchers==null){
//			searchers = Searchers.create();
//		}
//		if(condition!=null){
//			searchers.addCondition(condition);
//		}
//		return this;
//	}
	
	public static void main(String[] args) {
		
//		Searchers searchers = Searchers.create();
//		searchers.andEq("xxx", "vvvvvv");
//		searchers.andLike("xxx", "vvvvvv");
//		searchers.andGt("xxx", "vvvvvv");
//		searchers.andGe("xxx", "vvvvvv");
//		Finder finder = Finder.createForm(Type.class);
//
//		finder.addSearchers(searchers);
//		System.out.println(finder.getHql());
	}
	
	
	public Searchers createSearchers(Searcher searcher){
		Searchers searchers = Searchers.create(searcher);
		this.searchers = searchers;
		return searchers;
	}
	
	//这里SQL用成拼SQL方法，Value要过滤数据，这样就解决了那个问题啦
	private Finder addSearchers(){
		List<Condition> conditions = searchers.getConditions();
		if(conditions!=null){
			//把条件组成HQL，并回添加属性到parameters
			StringBuffer hql = new StringBuffer(" and(1=1");
			for (int i = 0; i < conditions.size(); i++) {
				Condition condition = conditions.get(i);
				hql.append(condition.getExpression(i));
				setValue(condition.getField().replaceAll("\\.", "_")+"_"+i, condition.getValue());
			}
			hql.append(")");
			
			hqlBuffer.append(hql);
		}
		return this;
	}
	
	public Finder setValue(String field, Object value){
		if(parameters == null){
			parameters = new HashMap<String, Object>();
		}
		
		if(parameters.containsKey(field)){
			throw new IllegalArgumentException("不能多次设置字段："+field);
		}
		
		parameters.put(field.replaceAll("\\.", "_"), value);
		
		return this;
	}
	
	public String getHql(){
		
		//添加搜索
		if(searchers!=null)
			addSearchers();
		
		//添加order
		if(pageOrder!=null){
			hqlBuffer.append(" order by " + pageOrder);
		System.out.println("====");
		}else if(order!=null){
			hqlBuffer.append(" " + order);
			System.out.println("-----");
		}
		
		System.out.println("finder :"+hqlBuffer.toString());
		return hqlBuffer.toString();
	}
	
	public Query setParameters(Query query){
		//设置是否开启缓存
		if(cacheable){
			query.setCacheable(true);
		}
		if(parameters!=null){
			for(String key : parameters.keySet()) {
				if(parameters.get(key) instanceof Date){
					query.setTimestamp(key, (Date)parameters.get(key));
				}else{
					query.setParameter(key, parameters.get(key));
				}
			} 
		}
		return query;
	}
	
	public String getCountHql(){
		String hqlString = hqlBuffer.toString();
		hqlString = hqlString.replaceFirst("(?i)from[\\s|-]", "from ");
		hqlString = hqlString.replaceFirst("[\\s|-](?i)order[\\s|-]", " order ");
		
		//这里可能有问题
		hqlString = hqlString.replaceAll("fetch", "");
		
		int fromIntex = hqlString.indexOf("from");
		if(fromIntex!=-1){
			hqlString = hqlString.substring(fromIntex, hqlString.length());
		}
		
		
		int orderIndex = hqlString.indexOf("order");
		if(orderIndex!=-1){
			hqlString = hqlString.substring(0,orderIndex);
		}
		
		hqlString = "select COUNT(*) "+hqlString;
		
		return hqlString;
	}
	
	private void checkHQL(String hql){
		if(hql.indexOf("'")!=-1){
			throw new IllegalArgumentException("需要购造的HQL中不能存在“'”，请以“:fieldName”为例");
		}
	}
	
	public void setCacheable(boolean b){
		this.cacheable = b;
	}
	
	public void setPageNo(int pageNo){
		this.pageNo = pageNo;
	}
	
	public void setPageSize(int pageSize){
		this.pageSize = pageSize;
	}
	
//	public int getPageNo(){
//		return this.pageNo;
//	}
	
	public int getFirstResult() {
		if(pageNo==0) pageNo=1;
		return (pageNo - 1) * pageSize;
	}
	
	public int getMaxResults() {
		return pageSize;
	}
	
}
